//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/.
// 			VisualNovelToolkit		     /_/_/_/_/_/_/_/_/_/.
// Copyright ©2013 - Sol-tribe.	/_/_/_/_/_/_/_/_/_/.
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/.
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

public class ByteCodes{
	private byte[] code;

	public ByteCodes(){		
	}

	public ByteCodes( byte[] code ){
		this.code = code;
	}

	public void  Init (){
		code = new byte[1];
		code[ 0 ] = Opcode.NULL;
	}

	public void  Add (  byte byt   ){
		List<byte> tempList = new List<byte>();
		for( int i=0;i<code.Length;i++){
			tempList.Add( code[ i ] );
		}		
		tempList.Add( byt );
		code = tempList.ToArray();		
	}
	
	public void  Add (  byte[] bytes   ){
		List<byte> tempList = new List<byte>();
		for( int i=0;i<code.Length;i++){
			tempList.Add( code[ i ] );
		}
		for( int i=0;i<bytes.Length;i++){
			tempList.Add( bytes[ i ] );
		}
		code = tempList.ToArray();
	}
	
	public void  Set (  byte bt  , int index ){
		code[ index ]= bt;
	}
	
	public void  AddInt (  int i   ){	
		Add( 1 );	//Opcode.ICONST
		byte[] bytes = System.BitConverter.GetBytes( i );	
		
		Add(  bytes[ 3 ] );	
		Add(  bytes[ 2 ] );	
		Add(  bytes[ 1 ] );	
		Add(  bytes[ 0 ] );	
	}
	
	public void  AddString (  string str   ){
		byte[] bytes = new byte[ 2 ];
		bytes[ 0 ]  = 5;// 5 : Opcode.STRING.
		bytes[ 1 ]  = (byte)str.Length;// 5 : Opcode.STRING.
		Add( bytes );
		
	 	byte[] temp = System.Text.Encoding.Unicode.GetBytes( str );		
		Add ( temp );
	}
	
	/*  Obsolete.
	public void  AddTablePairs (  Hashtable table   ){
		Add( 6 ); //Opcode.TABLE.
		Add( table.Keys.Count  );	// Key Counts.	
		foreach(string key in table.Keys) {
			StringLiteral strLit =  table[ key ] as StringLiteral;			
			if( strLit != null ){
				AddString( key  );
				AddString( strLit.GetTokenString() );			
				ViNoDebugger.Log( "key:" + key + "and val: " + table[ key ] as string );
			}else{
				TextLiteral txtLit =  table[ key ] as TextLiteral;			
				if( txtLit != null ){
					FIXME_VAR_TYPE str= txtLit.GetString().GetTokenString();
					AddString( key );					
					AddString( str );										
				}else{
					ViNoDebugger.LogError( " Compile Error . Not Added code : " + table[ key ] );
				}
			}
		}			
	}
	//*/
	
	// OBSOLETE.
	// Return Opcode.FUNC pos.
	public int AddStartOfFunction (  string name   ){		
		Add( Opcode.FUNC );	// Add Opcode.FUNC. pc
		Byte[] bytes = new Byte[4];		// int to byte array. 		pc +1 ~ 4
		int funcPos = GetCodePos();				
		Add( bytes );		
		AddString( name );		
		return funcPos;
	}
	
	// OBSOLETE.
	public void  AddEndOfFunction (  int funcPos   ){
		Add( Opcode.RETURN ); // Add Opcode.RETURN.
		int retPos = GetCodePos();			 
		byte[] bytes = System.BitConverter.GetBytes( retPos );				
		Set( bytes[ 0 ] , funcPos + 4 );
		Set( bytes[ 1 ] , funcPos + 3 );
		Set( bytes[ 2 ] , funcPos + 2 );
		Set( bytes[ 3 ] , funcPos + 1 );			
	}
	
	public void  _Log (){
		for( int j=0;j<code.Length;j++){
			ViNoDebugger.Log( "code : " + code[ j ] ) ;
		}		
	}
	
	public byte[] GetCode(){
		return code;	
	}
	
	public int GetCodeLength (){
		return code.Length;
	}
	
	public int GetCodePos (){
		return code.Length - 1;
	}
	
}